package com.yanmaohu.nikita.analyzer;

import com.yanmaohu.nikita.NikitaException;
import com.yanmaohu.nikita.data.TypeList;
import com.yanmaohu.nikita.data.Use;
import com.yanmaohu.nikita.data.UseList;
import com.yanmaohu.nikita.data.expression.NameExpression;
import com.yanmaohu.nikita.scanner.SourceCode;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author Bright Lee
 */
public class UseListAnalyzer {

    private final SourceCode sourceCode;
    private final TypeList typeList;

    public UseListAnalyzer(SourceCode sourceCode, TypeList typeList) {
        this.sourceCode = sourceCode;
        this.typeList = typeList;
    }

    public void analyze() {
        UseList useList = typeList.getUseList();
        if (useList == null || useList.isEmpty()) {
            return;
        }
        Map<String, Use> map1 = new HashMap<>();
        Map<String, Use> map2 = new HashMap<>();
        for (int i = 0; i < useList.size(); i++) {
            Use use = useList.get(i);
            String typeName = use.getTypeName();
            Use use2 = map2.get(typeName);
            if (use2 != null) {
                List<NameExpression> usedTypeName = use.getUsedTypeName();
                NameExpression nameExpression1 = usedTypeName.get(0);
                NameExpression nameExpression2 = usedTypeName.get(usedTypeName.size() - 1);
                throw new NikitaException(sourceCode, nameExpression1.getBeginIndex(), nameExpression2.getEndIndex(), "Duplicate type name.");
            }
            map2.put(typeName, use);
            String simpleTypeName = use.getSimpleTypeName();
            Use use1 = map1.get(simpleTypeName);
            if (use1 != null) {
                NameExpression alias = use.getAlias();
                if (alias != null) {
                    throw new NikitaException(sourceCode, alias.getBeginIndex(), alias.getEndIndex(), "Duplicate type name.");
                }
                List<NameExpression> usedTypeName = use.getUsedTypeName();
                NameExpression nameExpression = usedTypeName.get(usedTypeName.size() - 1);
                throw new NikitaException(sourceCode, nameExpression.getBeginIndex(), nameExpression.getEndIndex(), "Duplicate type name.");
            }
            map1.put(simpleTypeName, use);
        }
    }

}
